package com.jt.aop;

import jdk.nashorn.internal.scripts.JO;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
@Aspect//标识该类为AOP切面
public class SpringAOP {

   // @Before("bean(deptServiceImpl)")
   // @Before("within(com.jt.*.DeptServiceImpl)")
    /*
    com.jt.*.DeptServiceImpl   一级包下的类
    com.jt..*.DeptServiceImpl  ..代表多级包下的类
    com.jt..*   包下的所有的类

     */
   // @Before("execution(* com.jt..*.DeptServiceImpl.add*())")
    /*
    execution(* com.jt..*.DeptServiceImpl.add*())
    返回值类型任意,com.jt下所有包中的DeptServiceImpl的类的add开头的方法,并且没有参数
    execution(* com.jt..*.*(..))
    返回值类型任意,com.jt下的所有包的所有类的所有方法  任意参数
    execution(int com.jt..*.*(int))
    execution(integer com.jt..*.*(integer))
    在spring表达式中没有自动拆装箱功能
     */
    @Pointcut("@annotation(com.jt.anno.Cache)")
    public void pointcut(){

    }

    @Before("pointcut()")
    public void before(JoinPoint joinPoint){
        System.out.println("获取目标对象类型"+joinPoint.getTarget().getClass());
        System.out.println("获取目标对象类名"+joinPoint.getSignature().getDeclaringTypeName());
        System.out.println("获取目标对象方法名"+joinPoint.getSignature().getName());
        System.out.println("获取方法参数"+ Arrays.toString(joinPoint.getArgs()));
        System.out.println("before通知");
    }

@AfterReturning(pointcut = "pointcut()",returning = "result")
    public void afterReturning(JoinPoint joinPoint,Object result){
    System.out.println("用户的返回值结果"+result);
    System.out.println("afterReturning通知");
}

@AfterThrowing(pointcut = "pointcut()",throwing = "e")
    public  void afterThrowing(Exception e){
    System.out.println("afterThrowing通知");
    System.out.println("获取异常信息"+e.getMessage());
    System.out.println("获取异常类型"+e.getClass());
}
@After("pointcut()")
    public void after(){
    System.out.println("after通知");
    }

    @Around("pointcut()")
    /*
    控制目标法是否执行
    参数
    @return
     */
    public Object around(ProceedingJoinPoint joinPoint){
        Object result = null;
        try {
            System.out.println("环绕开始");
            long start  = System.currentTimeMillis();
           result = joinPoint.proceed();
           Long end = System.currentTimeMillis();
            System.out.println("耗时:"+(end-start));
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("环绕接收");
        return null;
    }
}
